#include <boost/bind.hpp>
#include <tbb/parallel_for.h>

#include "WorkFilter.h"
#include "WorkManager.h"

using namespace tbb;


// Constants
const size_t GrainSize = 10;

// Helper functions
void ProcessWork(WorksVector *works, int index)
{
	const Delegate &delegate = (*works)[index];
	(delegate.first->*(delegate.second))();
}

// Implementation

WorkFilter::WorkFilter()
	: filter(parallel)
{
	//
}

void *WorkFilter::operator()(void *arg)
{
	WorksVector *works = static_cast<WorksVector *>(arg);

	if (!works->empty())
	{
		if (works->size() == 1)
		{
			ProcessWork(works, 0);
		}
		else
		{
			// Call delegate for each work in parallel
			parallel_for(size_t(0), works->size(), GrainSize, boost::bind(&ProcessWork, works, _1));
		}
	}

	delete works;
	return NULL;
}